package org.happen.android.core.data.image;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

import org.happen.android.app.Globals;
import org.liushui.mycommons.android.log.McLog;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Environment;
import android.util.Log;

public class FilesUtils
{
	public static final String DEFAULT_SAVE_PATH = "";//= "/mnt/sdcard/download/file/image";
	static final String TAG = "FilesUtils";

	Context mContext;

	public FilesUtils(Context context)
	{
		this.mContext = context;
	}

	CacheInfo downloadImage(URL url)
	{
		Log.i(TAG, "downloadImage(); url = " + url.getPath());
		CacheInfo cacheInfo = null;
		if (!isNetworkConnected(mContext))
		{
			return null;
		}
		try
		{
			cacheInfo = new CacheInfo(url);
			int len = download(cacheInfo);
			cacheInfo.setFileSize(len);
		} catch (Exception ex)
		{
			Log.e(TAG, "exception", ex);
		}
		return cacheInfo;
	}

	boolean saveImage(Bitmap bitmap, String fileName)
	{
		boolean bool = false;
		BufferedOutputStream bos = null;
		BufferedInputStream bis = null;
		ByteArrayOutputStream baos = null;
		try
		{
			bos = new BufferedOutputStream(getSaveOutputStream(mContext, fileName));
			baos = new ByteArrayOutputStream();
			bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
			bis = new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray()));
			int b = -1;
			while ((b = bis.read()) != -1)
			{
				bos.write(b);
			}
			bool = true;
		} catch (Exception e)
		{
			bool = false;
			Log.i(this.mContext.getPackageName(), "the local storage is not available");
		} finally
		{
			try
			{
				if (bos != null)
				{
					bos.close();
				}
				if (bis != null)
				{
					bis.close();
				}

			} catch (IOException e)
			{
				bool = false;
				Log.i(this.mContext.getPackageName(), "the local storage is not available");
			}
		}
		return bool;
	}

	Bitmap readImage(String fileName)
	{
		Bitmap bm = null;
		InputStream is = null;
		try
		{

			is = new BufferedInputStream(getSaveInputStream(mContext, fileName));
			bm = BitmapFactory.decodeStream(is);
			is.close();
		} catch (FileNotFoundException e)
		{
			Log.e(this.mContext.getPackageName(), "image resource is not found int the cache directory", e);
		} catch (IOException e)
		{
			Log.e(this.mContext.getPackageName(), "input stream close exception", e);
		}
		return bm;
	}

	int download(CacheInfo cacheInfo)
	{
		int len = 0;
		BufferedOutputStream bos = null;
		BufferedInputStream is = null;
		try
		{
			bos = new BufferedOutputStream(getSaveOutputStream(mContext, cacheInfo.getFileName()));
			URLConnection conn = cacheInfo.getUrl().openConnection();
			len = conn.getContentLength();
			is = new BufferedInputStream(conn.getInputStream());
			byte[] buffer = new byte[1024 * 4];
			int length = -1;
			while ((length = is.read(buffer)) != -1)
			{
				bos.write(buffer, 0, length);
			}
			bos.flush();
		} catch (Exception ex)
		{
			Log.e(TAG, "exception", ex);
		} finally
		{
			try
			{
				if (is != null)
				{
					is.close();
				}
				if (bos != null)
				{
					bos.close();
				}
			} catch (Exception e)
			{
				Log.e(TAG, "exception", e);
			}
		}
		return len;
	}

	boolean deleteImage(String fileName)
	{
		return this.mContext.deleteFile(fileName);
	}

	static InputStream getSaveInputStream(Context mContext, String filename)
	{
		FileInputStream fis = null;
		if (isSdAvailable())
		{
			try
			{
				checkDir();
				fis = new FileInputStream(new File(Globals.APP_FILE_IMAGE_PATH, filename));
			} catch (FileNotFoundException e)
			{
				e.printStackTrace();
			}
		} else
		{
			try
			{
				fis = mContext.openFileInput(filename);
			} catch (FileNotFoundException e)
			{
				e.printStackTrace();
			}
		}
		return fis;
	}

	static void checkDir()
	{
		File parent = new File(Globals.APP_FILE_IMAGE_PATH);
		if (!parent.exists())
		{
			parent.mkdirs();
		}
	}

	static FileOutputStream getSaveOutputStream(Context mContext, String filename)
	{
		FileOutputStream fos = null;
		if (isSdAvailable())
		{
			try
			{
				checkDir();
				File file = new File(Globals.APP_FILE_IMAGE_PATH, filename);
				fos = new FileOutputStream(file);
			} catch (FileNotFoundException e)
			{
				e.printStackTrace();
			}
		} else
		{
			try
			{
				fos = mContext.openFileOutput(filename, 0);
			} catch (FileNotFoundException e)
			{
				e.printStackTrace();
			}
		}
		McLog.i("fos = " + fos);
		return fos;
	}

	/**
	 * 网络是否连接
	 * 
	 * @ReqParam context
	 * @return
	 */
	public static boolean isNetworkConnected(Context context)
	{
		if (context != null)
		{
			ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
			NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
			if (mNetworkInfo != null)
			{
				return mNetworkInfo.isAvailable();
			}
		}
		return false;
	}

	/**
	 * sdcard是否可用
	 * 
	 * @return
	 */
	public static boolean isSdAvailable()
	{
		return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
	}
}